package com.ficus.road.maintain.util;

import cn.hutool.http.HttpUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.net.URLEncoder;

/**
 * @author xiawen yang
 * @date 2021/11/25 下午4:45
 */
@Slf4j
public class DingDingMsgSendUtil {

    /**
     * 发送钉钉群消息（link类型）
     *
     * @param accessToken
     * @param title       消息标题
     * @param text        消息内容。如果太长只会部分展示
     * @param messageUrl  点击消息跳转的URL
     */
    public static void sendDingDingLinkGroupMsg(String accessToken, String secret, String title, String text, String messageUrl) {
        String textMsg = "{\n" +
                "    \"msgtype\": \"link\", \n" +
                "    \"link\": {\n" +
                "        \"text\": \"" + text + "\", \n" +
                "        \"title\": \"" + title + "\", \n" +
                "        \"picUrl\": \"\", \n" +
                "        \"messageUrl\": \"" + messageUrl + "\"\n" +
                "    }\n" +
                "}";
        dealDingDingMsgSend(accessToken, secret, textMsg);
    }

    /**
     * 整体跳转ActionCard类型
     *
     * @param accessToken
     * @param title
     * @param text
     * @param singleTitle
     * @param singleURL
     */
    public static void sendDingDingActionCardGroupMsg(String accessToken, String secret, String title, String text, String singleTitle, String singleURL) {
        String textMsg = "{\n" +
                "    \"actionCard\": {\n" +
                "        \"title\": \"" + title + "\", \n" +
                "        \"text\": \"" + text + "\", \n" +
                "        \"hideAvatar\": \"0\", \n" +
                "        \"btnOrientation\": \"0\", \n" +
                "        \"singleTitle\" : \"" + singleTitle + "\",\n" +
                "        \"singleURL\" : \"" + singleURL + "\"\n" +
                "    }, \n" +
                "    \"msgtype\": \"actionCard\"\n" +
                "}";
        dealDingDingMsgSend(accessToken, secret, textMsg);
    }

    /**
     * 调用钉钉官方接口发送钉钉消息（新版本，需要配置安全设置）
     *
     * @param accessToken
     * @param secret
     * @param textMsg
     */
    private static void dealDingDingMsgSend(String accessToken, String secret, String textMsg) {
        Long timestamp = System.currentTimeMillis();
        String sign = getSign(secret, timestamp);
        String url = "https://oapi.dingtalk.com/robot/send?access_token=" + accessToken + "&timestamp=" + timestamp + "&sign=" + sign;
        try {
            log.info("【发送钉钉群消息】请求参数：url = {}, textMsg = {}", url, textMsg);
            String res = HttpUtil.post(url, textMsg);
            log.info("【发送钉钉群消息】消息响应结果：" + res);
        } catch (Exception e) {
            log.warn("【发送钉钉群消息】请求钉钉接口异常，errMsg = {}", e);
        }
    }

    /**
     * 计算签名
     *
     * @param secret    密钥，机器人安全设置页面，加签一栏下面显示的SEC开头的字符
     * @param timestamp
     * @return
     */
    private static String getSign(String secret, Long timestamp) {
        try {
            String stringToSign = timestamp + "\n" + secret;
            Mac mac = Mac.getInstance("HmacSHA256");
            mac.init(new SecretKeySpec(secret.getBytes("UTF-8"), "HmacSHA256"));
            byte[] signData = mac.doFinal(stringToSign.getBytes("UTF-8"));
            String sign = URLEncoder.encode(new String(Base64.encodeBase64(signData)), "UTF-8");
            log.info("【发送钉钉群消息】获取到签名sign = {}", sign);
            return sign;
        } catch (Exception e) {
            log.error("【发送钉钉群消息】计算签名异常，errMsg = {}", e);
            return null;
        }
    }
}
